package lvq;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class MatrizU extends JPanel {

	private Rede rede;

	private double[][] matriz;
	private double escala;

	public MatrizU(Rede rede) {

		this.rede = rede;
		matriz = new double[rede.altura() * 2 - 2][rede.largura() * 2 - 2];

		criaMatriz();
		determinaEscala();
	}

	private void criaMatriz() {

		for (int i = 0; i < rede.altura() - 1; i++) {
			for (int j = 0; j < rede.largura() - 1; j++) {

				int x = i * 2;
				int y = j * 2;

				Neuronio neuronio = rede.neuronios()[i][j];

				Neuronio esquerda = rede.neuronios()[i][j + 1];
				matriz[x][y + 1] = neuronio.distanciaEuclidiana(esquerda);

				Neuronio baixo = rede.neuronios()[i + 1][j];
				matriz[x + 1][y] = neuronio.distanciaEuclidiana(baixo);

				Neuronio diagonal = rede.neuronios()[i + 1][j + 1];
				matriz[x + 1][y + 1] = neuronio.distanciaEuclidiana(diagonal);

				matriz[x][y] = (matriz[x][y + 1] + matriz[x + 1][y] + matriz[x + 1][y + 1]) / 3;
			}
		}
	}

	private void determinaEscala() {

		double max = Double.MIN_VALUE;
		double min = Double.MAX_VALUE;

		for (int i = 0; i < matriz.length; i++) {
			for (int j = 0; j < matriz[i].length; j++) {

				if (matriz[i][j] > max) {
					max = matriz[i][j];
				}
				if (matriz[i][j] < min) {
					min = matriz[i][j];
				}
			}
		}

		escala = max - min;
	}

	@Override
	public final void paint(Graphics g1) {

		Graphics2D g = inicializaPainel(g1);

		imprimeMatriz(g);
	}

	private Graphics2D inicializaPainel(Graphics g1) {

		Graphics2D g = (Graphics2D) g1;

		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

		g.setColor(Color.WHITE);
		g.fillRect(0, 0, rede.altura() * 4, rede.largura() * 4);

		return g;
	}

	private void imprimeMatriz(Graphics2D g) {

		for (int i = 0; i < matriz.length; i++) {
			for (int j = 0; j < matriz[i].length; j++) {
				imprimePixel(g, i, j);
			}
		}
	}

	private void imprimePixel(Graphics2D g, int i, int j) {

		int codigoCor = (int) (255 - (matriz[i][j] * 255 / escala));

		Color cor = new Color(codigoCor, codigoCor, codigoCor);
		g.setColor(cor);

		int x = i * 10;
		int y = j * 10;
		Rectangle2D.Double pixel = new Rectangle2D.Double(x, y, 10, 10);
		g.fill(pixel);
	}

	public void mostraDados() {

		int tamanhoJanelaX = rede.altura() * 20 + 16;
		int tamanhoJanelaY = rede.largura() * 20 + 39;

		JFrame frame = new JFrame();

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setTitle("U-Matrix");
		frame.setBounds(50, 50, tamanhoJanelaX, tamanhoJanelaY);
		frame.setContentPane(this);

		frame.setVisible(true);
	}
}
